package com.foreknow.spring;

import com.foreknow.model.User;
import com.foreknow.service.UserService;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ClassPathXmlApplicationContext implements  BeanFactory {
  //创建一个Map容器
  private Map<String,Object> beans = new HashMap<String, Object>();
  //在构造中要解析beans.xml文件
  public ClassPathXmlApplicationContext() throws Exception {
    //创建jdm中提供好的SAXBuilder对象
    SAXBuilder saxBuilder = new SAXBuilder();
    //读取beans.xml文件并构造文档对象Document
    Document doc = saxBuilder.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));
    //获取到根元素
    Element root = doc.getRootElement();
    //获取到子元素<bean>
    List list = root.getChildren();
    for(int i = 0;i<list.size();i++){
      Element element = (Element) list.get(i);
      //获取到bean中的属性值  <bean id="u" class="com.foreknow.dao.Impl.UserDAOImpl"></bean>
      String id = element.getAttributeValue("id"); //u
      String clazz = element.getAttributeValue("class"); //com.foreknow.dao.Impl.UserDAOImpl
      //我们需要将clazz转换为Object对象,需要用到反射
      Object o = Class.forName(clazz).newInstance();
      //将获取到的id以及o保存到Map容器中
      beans.put(id,o);
      //获取到bean中的property
      //<bean id="userService" class="com.foreknow.service.UserService">
        //<property name="userDAO" bean="u"></property>
      //</bean>
      for(Element propertyElement:(List<Element>)element.getChildren("property")){
        String name = propertyElement.getAttributeValue("name"); //userDAO
        String bean = propertyElement.getAttributeValue("bean"); //u
        //获取map容器中的UserDAOImpl
        Object beanObject = beans.get(bean); //UserDAOImpl对象
        //调用public void setUserDAO(UserDAO userDAO)方法
        String methodName = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
        //beanObject.getClass().getInterfaces()[0]形参-------UserDAO
        Method method = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]);
        //调用set方法  o:UserService对象  beanObject就是UserDAO接口的实现类的对象（实际参数）
        method.invoke(o,beanObject);
      }
    }
  }
  public Object getBean(String id) {
    return beans.get(id);
  }

  public static void main(String[] args) throws Exception {
//    BeanFactory beanFactory = new ClassPathXmlApplicationContext();
//    UserService service = new UserService();
//    UserDAO userDAO = (UserDAO) beanFactory.getBean("u");
//    service.setUserDAO(userDAO);
//    service.add(new User());

    BeanFactory factory = new ClassPathXmlApplicationContext();
    UserService userService = (UserService) factory.getBean("userService");
    userService.add(new User());


  }
    }
